home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / pvquan16.zip / QUANT / FILES.C next >
C/C++ Source or Header  |  1992-11-30  |  11KB  |  347 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1991, Frank van der Hulst             *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * Authors:                                                             *
  7.  *        FvdH - Frank van der Hulst (Wellington, NZ)                   *
  8.  *                                                                      *
  9.  * Versions:                                                            *
  10.  *    V1.1 910626 FvdH - QUANT released for DBW_RENDER                  *
  11.  *    V1.2 911021 FvdH - QUANT released for PoV Ray                     *
  12.  *    V1.3 911030 FvdH - Added 320x200x256x4 pages support              *
  13.  *                     - Fixed bug in output_anim_files                 *
  14.  *    V1.4 920303 FvdH - Ported to GNU C                                *
  15.  *    V1.5 920331 FvdH - Allow Targa input                              *
  16.  *         920403 FvdH - Allow any number of files                      *
  17.  *    V1.6 921023 FvdH - Produce multi-image GIFs                       *
  18.  *                     - Port to OS/2 IBM C Set/2                       *
  19.  *                                                                      *
  20.  ************************************************************************/
  21.  
  22. #include <string.h>
  23. #ifdef __TURBOC__
  24. #include <dos.h>
  25.  
  26. #define SC_INDEX           0x3c4
  27. #define MAP_MASK           2
  28. #endif
  29.  
  30. #ifdef __GNUC__
  31. #define SEEK_SET 0
  32. #endif
  33.  
  34. #include "gif_lib.h"
  35. #include "quant.h"
  36.  
  37. int (*get_pixel)(UCHAR *pixel);
  38.  
  39. static FILE *out_file;
  40. static FILE *in_file[3];
  41.  
  42. static int get_pixel_raw(UCHAR *pixel)
  43. {
  44.     int t;
  45.  
  46. #if INPUT_BITS == 8
  47.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  48.     pixel[BLUE] = t;
  49.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  50.     pixel[GREEN] = t;
  51.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  52.     pixel[RED] = t;
  53. #else
  54. #define MAX_IN  ((0xff << (8 - INPUT_BITS)) & 0xff)
  55. #define ROUND   (1 << (7 - INPUT_BITS))
  56. #define R_SHIFT (8 - INPUT_BITS)
  57.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  58.     pixel[BLUE]  = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  59.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  60.     pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  61.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  62.     pixel[RED]   = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  63. #undef MAX_IN
  64. #undef ROUND
  65. #undef R_SHIFT
  66. #endif
  67.     return TRUE;
  68. }
  69.  
  70.  
  71. static int get_pixel_targa(UCHAR *pixel)
  72. {
  73.     int t;
  74.  
  75. #if INPUT_BITS == 8
  76.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  77.     pixel[BLUE] = t;
  78.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  79.     pixel[GREEN] = t;
  80.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  81.     pixel[RED] = t;
  82. #else
  83. #define MAX_IN  ((0xff << (8 - INPUT_BITS)) & 0xff)
  84. #define ROUND   (1 << (7 - INPUT_BITS))
  85. #define R_SHIFT (8 - INPUT_BITS)
  86.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  87.     pixel[BLUE]  = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  88.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  89.     pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  90.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  91.     pixel[RED]   = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  92. #undef MAX_IN
  93. #undef ROUND
  94. #undef R_SHIFT
  95. #endif
  96.     return TRUE;
  97. }
  98.  
  99.  
  100. /* The "+ft" option of PVRAY writes out Targa format.  Specifically, the
  101.     fields are:
  102.  
  103. Header:
  104.    00 00 02 00 00      - Fixed header information for uncompressed type 2 image
  105.    00 00 00
  106.    0000                - Horizontal offset always is at 0000
  107.     llll                - Vertical offset (1st line number, 16 bits, LSB first)
  108.     wwww hhhh           - width, height of image (16 bits each, LSB first)
  109.    18 20               - 24 bits per pixel, Top-down raster
  110.  
  111. For each line:
  112.     bb gg rr bb gg rr ... - blue, green, and red data, 8 bits for each pixel.
  113. */
  114.  
  115. void open_file(char *fname, int num)
  116. {
  117. char filename[256];
  118.  
  119.     if (input_type == 0) {
  120.         sprintf(filename, "%s_%d.red", fname, num);
  121.         if ((in_file[0] = fopen(filename, "rb")) == NULL) {
  122.             printf("Cannot open %s.\n", filename);
  123.             err_exit();
  124.         }
  125.         sprintf(filename, "%s_%d.grn", fname, num);
  126.         if ((in_file[1] = fopen(filename, "rb")) == NULL) {
  127.             printf("Cannot open %s.\n", filename);
  128.             err_exit();
  129.         }
  130.         sprintf(filename, "%s_%d.blu", fname, num);
  131.         if ((in_file[2] = fopen(filename, "rb")) == NULL) {
  132.             printf("Cannot open %s.\n", filename);
  133.             err_exit();
  134.         }
  135.         get_pixel = get_pixel_raw;
  136.         return;
  137.     }
  138.     if (input_type == 1) {
  139.         sprintf(filename, "%s_%d.tga", fname, num);
  140.         if ((in_file[0] = fopen(filename, "rb")) == NULL) {
  141.             printf("Cannot open %s.\n", filename);
  142.             err_exit();
  143.         }
  144.         fseek(in_file[0], 18, SEEK_SET);        /* Skip header */
  145.         get_pixel = get_pixel_targa;
  146.         return;
  147.     }
  148. }
  149.  
  150. void close_file(void)
  151. {
  152.     fclose(in_file[0]);
  153.     if (input_type == 0) {
  154.         fclose(in_file[1]);
  155.         fclose(in_file[2]);
  156.     }
  157. }
  158.  
  159. void write_4_planes(char *infname, int num, UINT Xres, UINT Yres)
  160. {
  161.     UINT plane, x, y;
  162.     UCHAR pixel[3];
  163.     char more_data;
  164.     char dummy[3];
  165. #ifdef __TURBOC__
  166.     char far *VGA_addr = MK_FP(0xa000,0);
  167. #endif
  168.  
  169.     open_file(infname, num);
  170.     for (plane = 0; plane < 4; plane++) {
  171.         more_data = 1;
  172.         fseek(in_file[0], (long)plane, SEEK_SET);
  173.         fseek(in_file[1], (long)plane, SEEK_SET);
  174.         fseek(in_file[2], (long)plane, SEEK_SET);
  175. #ifdef __TURBOC__
  176.         if (disp_image)     outport(SC_INDEX, (0x100 << plane) | MAP_MASK);
  177. #endif
  178.         for (y = 0; y < Yres; y++) {
  179.             for (x = plane; x < Xres; x += 4) {
  180.                 if (more_data) {
  181.                     if (!get_pixel(pixel))
  182.                         pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  183.                     else {
  184.                         fread(dummy, 3, 1, in_file[0]);   /* Skip to next pixel for this plane */
  185.                         fread(dummy, 3, 1, in_file[1]);
  186.                         fread(dummy, 3, 1, in_file[2]);
  187.                     }
  188.                     putc(pal_index(pixel), out_file);
  189. #ifdef __TURBOC__
  190.                     if (disp_image)        *VGA_addr++ = pal_index(pixel);
  191. #endif
  192.                 } else    putc(pal_index(pixel), out_file);
  193.             }
  194.         }
  195.     }
  196.     close_file();
  197. }
  198.  
  199. static void write_linear(char *infname, int num, UINT Xres, UINT Yres)
  200. {
  201.     UINT x, y;
  202.     UCHAR pixel[3];
  203.     char more_data;
  204. #ifdef __TURBOC__
  205.     char far *VGA_addr = MK_FP(0xa000,0);
  206. #endif
  207.  
  208.     open_file(infname, num);
  209.     more_data = 1;
  210.     for (y = 0; y < Yres; y++) {
  211.         for (x = 0; x < Xres; x++) {
  212.             if (more_data) {
  213.                 if (!get_pixel(pixel))
  214.                     pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  215.             }
  216.             putc(pal_index(pixel), out_file);
  217. #ifdef __TURBOC__
  218.             if (disp_image) {
  219.                 outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
  220.                 VGA_addr[y*(320/4)+x/4] = pal_index(pixel);
  221.             }
  222. #endif
  223.         }
  224.     }
  225.     close_file();
  226. }
  227.  
  228. /****************************************************************************
  229.     Convert Raw image (One byte per pixel) into Gif file. Raw data is read
  230.     from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
  231.     bytes are read. Color map is dumped from ColorMap.
  232. */
  233.  
  234. static void output_gif_file(char *infname, int num_files, char *out_fname, UINT Xres, UINT Yres, UINT num_colours)
  235. {
  236.    int i, x, y;
  237.    UCHAR pixel[3];
  238.    UCHAR *ScanLine;
  239.  
  240.    for (i = 0; i < 8 && (2 << i) < num_colours; i++);
  241.    num_colours = 2 << i;
  242.    if (num_colours > 256) {
  243.       printf("Colour map must be less than 256 colours.\n");
  244.       err_exit();
  245.    }
  246.  
  247.    printf("\nImage size is %dx%d:     ", Xres, Yres);
  248.  
  249.    if (EGifOpenFileName(out_fname) == -1)    return;
  250.    EGifPutScreenDesc(Xres, Yres, 6, 0, 8, palette);
  251.  
  252.    for (i = 0; i < num_files ; i++) {
  253.       open_file(infname, i);
  254.       EGifPutImageDesc(0, 0, Xres, Yres, 8);
  255.  
  256.       CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
  257.  
  258.       /* Here it is - get one raw line from input file, and dump to Gif: */
  259.       for (y = 0; y < Yres; y++) {
  260.       /* Note we assume here PixelSize == Byte, which is not necessarily   */
  261.       /* so. If not - must read one byte at a time, and coerce to pixel.   */
  262.          for (x = 0